﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Eneta.Portal.Common;
using Eneta.Portal.Common.Dto;
using Eneta.Portal.Common.Helpers;
using Eneta.Portal.Common.Repository;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Utilities;

using FredCK.FCKeditorV2;

namespace Eneta.Portal.NewsAndBlogs.Pages
{
    public class AddAnnoucement : Page
    {
        protected Button saveButton;
        protected HtmlGenericControl messageBox;
        protected Label messageLabel;

        protected TextBox titleField;
        //protected TextBox shortDescriptionField;
        protected FCKeditor shortDescriptionField;
        //protected CheckBoxList companiesList;
        protected DropDownList companiesDropDown;

        private AnnouncementDto _item;

        protected AnnouncementDto Item
        {
            get
            {
                if (_item != null)
                    return _item;

                var id = Helper.GetIdFromQueryString(Request.QueryString["aid"]);
                if (id == 0)
                    return null;
                
                var rep = new AnnouncementRepository(SPContext.Current.Web);
                _item = rep.GetAnnouncementById(id);
                return _item;
            }
        }
        
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            saveButton.Click += SaveButtonClick;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            var query = "";
            if (!string.IsNullOrEmpty(Request.QueryString["ID"]))
                query += "&aid=" + Request.QueryString["ID"];
            if (!string.IsNullOrEmpty(Request.QueryString["Owner"]))
                query += "&owner=" + Request.QueryString["Owner"];

            if (!string.IsNullOrEmpty(query))
                query = "?" + query.Substring(1);

            Response.Redirect("/uudised/teated/Lehed/add.aspx" + query);
            Response.End();
            return;

            var currentUser = SPContext.Current.Web.CurrentUser;
            if(currentUser == null)
            {
                Response.Redirect("/");
                return;
            }

            if (Item != null)
            {
                if (string.IsNullOrEmpty(Item.OwnerUserName))
                {
                    Response.Redirect("/");
                    return;
                }

                if (Item.OwnerUserName != currentUser.LoginName)
                    if (!currentUser.IsSiteAdmin)
                    {
                        Response.Redirect("/");
                        return;
                    }
            }

            messageBox.Visible = false;
            messageLabel.Text = string.Empty;
            
            if (IsPostBack)
                return;

            BindCompanies();
            //shortDescriptionField.Attributes.Add("onKeyDown", "return textCounter(this,event)");
            //shortDescriptionField.Attributes.Add("onKeyUp", "return textCounter(this,event)");

            if (Item == null)
                return;

            titleField.Text = Item.Title;
            
            //shortDescriptionField.Text = Item.Body;
            shortDescriptionField.Value = Item.Body;

            
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            RegisterClientScriptBlock("descrField", "<script>var descrFieldId='" +  shortDescriptionField.ClientID + "';</script>");
            messageBox.Visible = !string.IsNullOrEmpty(messageLabel.Text);
            SetCheckStyles(Controls);
        }

        private static void SetCheckStyles(ControlCollection controls)
        {
            foreach (Control c in controls)
                if (c.GetType() == typeof(CheckBox))
                    ((CheckBox)c).InputAttributes["class"] = "choice";
                else if (c.HasControls())
                    SetCheckStyles(c.Controls);

        }

        protected void SaveButtonClick(object sender, EventArgs e)
        {
            var profile = SPContext.Current.Web.CurrentUser.GetUserProfile();
            string operation;
            if(profile == null)
            {
                Response.Redirect("/", false);
                return;
            }

            var name = titleField.Text;            

            var errors = new Dictionary<string, string>();

            if (string.IsNullOrEmpty(name))
            {
                errors.Add("title", "Teate pealkirja ei sisestatud");
            }
            else if (name.Length > 255)
            {
                errors.Add("title", "Teate pealkiri ei saa olla pikem kui 255 tähemärki");
            }

            //if (string.IsNullOrEmpty(shortDescriptionField.Text))
            if (string.IsNullOrEmpty(shortDescriptionField.Value))
            {
                errors.Add("shortDescription", "Teate lühikirjeldust ei sisestatud");
            }
            
            if (errors.Count > 0)
            {
                ApplyErrors(errors);
                return;
            }

            Logger.LogInfo("SaveButtonClick(): adding approver role to user", GetType().ToString());
            AddApproverRoleToUser();

            try
            {
                throw new Exception("VIGA!");
                if (Item == null)
                {
                    Logger.LogInfo("SaveButtonClick(): adding new page", GetType().ToString());
                    SavePage();
                    Logger.LogInfo("SaveButtonClick(): page added", GetType().ToString());
                    operation = "annsave";
                }
                else
                {
                    Logger.LogInfo("SaveButtonClick(): adding approver role to user", GetType().ToString());
                    UpdatePage();
                    operation = "annedit";
                }  
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                messageLabel.Text = "Teate salvestamine ebaõnnestus tehnilistel põhjustel";
                RemoveApproverRoleFromUser();
                return;
            }

            RemoveApproverRoleFromUser();

            if (Item == null)
            {

                var currentUser = SPContext.Current.Web.CurrentUser;
                var body = "<html><body style=\"font-family:arial;font-size:10pt\">";
                body += "<p>Hei " + currentUser.Name + "!</p>";
                body += "<p>Tänud teate \"" + titleField.Text + "\" lisamise eest Eneta portaali. ";
                body += "Teade ilmub peale administraatori poolset kinnitamist.</p>";

                body += "<p>Tervitustega,<br/>";
                body += "Eneta tiim</p>";
                body +=
                    "<a href=\"http://www.eneta.ee\"><img src=\"http://www.eneta.ee/SiteCollectionImages/logod/eneta_logo_250x78_sinine.png\" border=\"0\"></a>";
                body += "</body></html>";

                SPUtility.SendEmail(SPContext.Current.Web, false, false, profile["Email"].ToString(),
                                    "Lisasid teate Eneta portaali", body);
                SPUtility.SendEmail(SPContext.Current.Web, false, false, "abi@eneta.ee", "Lisasid teate Eneta portaali",
                                    body);
                
            }
            int userId;
            if (IsCurrentUser(out userId))
                Response.Redirect("/profile.aspx?id=" + profile.ID + "&msg="+ operation, false);
            else
                Response.Redirect("/profile.aspx?id=" + userId + "&msg=" + operation, false);
        }

        private bool IsCurrentUser(out int userId)
        {
            string owner = Request.QueryString["Owner"];
            if (string.IsNullOrEmpty(owner))
            {
                userId = -1;
                return true;
            }
            int ownerId;
            if (!int.TryParse(owner, out ownerId))
            {
                userId = -1;
                return true;
            }
            userId = ownerId;
            return false;
        }

        private void UpdatePage()
        {
            //var sec = new SPSecurity.CodeToRunElevated(delegate
            //{
            var siteId = SPContext.Current.Web.Site.ID;
            using (var site = new SPSite(siteId))
            using (var web = site.OpenWeb("/uudised/teated/"))
            {
                var list = web.Lists["Lehed"];
                var item = list.GetItemById(Item.Id);
                var status = item.ModerationInformation.Status;

                var dto = new AdminActivityDto();
                dto.PreviousEditor = new SPFieldUserValue(web, item["Editor"].ToString()).User.LoginName;
                dto.PreviousStatus = item.ModerationInformation.Status;
                dto.PreviousTimeStamp = (DateTime) item["Modified"];
                dto.Url = "/uudised/teated/announcementview.aspx?id" + item.ID;
                dto.Module = "Announcements";

                var pubItem = PublishingPage.GetPublishingPage(item);
                if (pubItem.ListItem.File.CheckOutStatus == SPFile.SPCheckOutStatus.None)
                    pubItem.CheckOut();
                pubItem.Title = titleField.Text;
                //pubItem.ListItem["PublishingPageContent"] = shortDescriptionField.Text;
                Logger.LogInfo(
                    "AddAnnouncement.UpdatePage: html = " +
                    RegExHelper.RemoveForbiddenAttributes(shortDescriptionField.Value), "");                
                item["PublishingPageContent"] = RegExHelper.RemoveForbiddenAttributes(shortDescriptionField.Value);

                //var selectedCompanies = GetSelectedCompanyIds();
                //if(selectedCompanies.Count > 0)
                Logger.LogInfo("AddAnnouncement.UpdatePage(): selected company = " + companiesDropDown.SelectedValue, "AddAnnouncement");
                if (!string.IsNullOrEmpty(companiesDropDown.SelectedValue))
                {
                    Logger.LogInfo("AddAnnouncement.UpdatePage(): assigning company", "AddAnnouncement");
                    var companiesValue = new SPFieldLookupValueCollection();
                    var companyRepository = new CompanyRepository(SPContext.Current.Web);

                    var companyId = int.Parse(companiesDropDown.SelectedValue);
                    var company = companyRepository.GetCompanyById(companyId);
                    var companyValue = new SPFieldLookupValue(
                                                company.Id,
                                                company.Title
                                            );
                    companiesValue.Add(companyValue);                    
                    var fieldId = item.Fields.GetFieldByInternalName("Companies").Id;
                    item[fieldId] = companiesValue;
                    Logger.LogInfo("AddAnnouncement.UpdatePage(): company value = " + item[fieldId], "AddAnnouncement");
                }
                else
                {
                    Logger.LogInfo("AddAnnouncement.UpdatePage(): company is null", "AddAnnouncement");
                    var fieldId = item.Fields.GetFieldByInternalName("Companies").Id;
                    item[fieldId] = null;
                }

                item.Update();
                //pubItem.ListItem.ParentList.Update();
                item.File.CheckIn("Muudetud", SPCheckinType.MajorCheckIn);
                
                if(status == SPModerationStatusType.Approved)
                    item.File.Approve(string.Empty);

                var tmpItem = item.ParentList.GetItemById(item.ID);
                Logger.LogInfo("AddAnnouncement.UpdatePage(): html after sp: " + item["PublishingPageContent"], "AddAnnouncement");
                

                dto.CurrentEditor = new SPFieldUserValue(web, item["Editor"].ToString()).User.LoginName;
                dto.CurrentStatus = item.ModerationInformation.Status;
                dto.CurrentTimeStamp = (DateTime)item["Modified"];
                ActivityLogger.LogActivity(dto);
            }
        }

        private int _currentID;
        private int CurrentID
        {
            get
            {
                if (_currentID != 0)
                    return 0;

                int.TryParse(Request.QueryString["CurrentID"] ?? string.Empty, out _currentID);
                return _currentID;
            }
        }

        private void SavePage()
        {
            var siteId = SPContext.Current.Site.ID;
            var userId = SPContext.Current.Web.CurrentUser.LoginName;

            //var sec = new SPSecurity.CodeToRunElevated(delegate
            //{
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/uudised/teated/"))
                    {
                        var page = CurrentID == 0 ? CreatePage(web) : GetPage(web);
                        var item = page.ListItem;

                        var fieldId = item.Fields.GetFieldByInternalName("PublishingPageContent").Id;
                        item[fieldId] = shortDescriptionField.Value;

                        fieldId = item.Fields.GetFieldByInternalName("Author").Id;
                        item[fieldId] = web.SiteUsers[userId];

                        fieldId = item.Fields.GetFieldByInternalName("RealAuthor").Id;
                        item[fieldId] = web.SiteUsers[userId];

                        //var selectedCompanies = GetSelectedCompanyIds();
                        //if(selectedCompanies.Count > 0)
                        if (!string.IsNullOrEmpty(companiesDropDown.SelectedValue))
                        {
                            var companiesValue = new SPFieldLookupValueCollection();
                            var companyRepository = new CompanyRepository(SPContext.Current.Web);

                            //foreach(var companyId in selectedCompanies)
                            //{
                            //    var company = companyRepository.GetCompanyById(companyId);
                            //    if (company == null)
                            //        continue;

                            //    var companyValue = new SPFieldLookupValue(
                            //                            company.Id, 
                            //                            company.Title 
                            //                        );
                            //    companiesValue.Add(companyValue);
                            //}
                            var companyId = int.Parse(companiesDropDown.SelectedValue);
                            var company = companyRepository.GetCompanyById(companyId);
                            var companyValue = new SPFieldLookupValue(
                                                        company.Id, 
                                                        company.Title 
                                                    );
                            companiesValue.Add(companyValue);

                            fieldId = item.Fields.GetFieldByInternalName("Companies").Id;
                            item[fieldId] = companiesValue;
                        }
                        else
                        {
                            fieldId = item.Fields.GetFieldByInternalName("Companies").Id;
                            item[fieldId] = null;
                        }
                        
                        item.Update();

                        item.File.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
                        item.File.Update();
                    }
                }
            //});
            //SPSecurity.RunWithElevatedPrivileges(sec);
            var profile = SPContext.Current.Web.CurrentUser.GetUserProfile();
            Response.Redirect("/profile.aspx?ID=" + profile.ID + "&msg=annsave", false);
        }

        private PublishingPage GetPage(SPWeb web)
        {
            var list = web.Lists["Lehed"];
            var item = list.GetItemById(CurrentID);

            return PublishingPage.GetPublishingPage(item);
        }

        private PublishingPage CreatePage(SPWeb web)
        {
            var publishingWeb = PublishingWeb.GetPublishingWeb(web);

            var ct = web.AvailableContentTypes["Uudis"];

            if(ct == null)
                foreach (SPContentType ct2 in web.AvailableContentTypes)
                {
                    Logger.LogInfo("SaveButtonClick: CT: |" + ct2.Name +"|", "CompanyEditPage");
                    if (ct2.Name == "Uudis")
                    {
                        ct = ct2;
                    }
                }
            if (ct == null)
                Logger.LogInfo("AddAnnouncement.CreatePage(): news layout: CT Uudis is null", GetType().ToString());

            var pageName = UrlHelper.GetPageFileName(titleField.Text);

            Logger.LogInfo("AddAnnouncement.CreatePage(): news layout: Getting page layouts", GetType().ToString());
            var layouts = publishingWeb.GetAvailablePageLayouts(ct.Id);
            Logger.LogInfo("AddAnnouncement.CreatePage(): layouts tretrieved for ct Uuudised: " + layouts.Length, GetType().ToString());
            var newsLayout = layouts[0];

            Logger.LogInfo("AddAnnouncement.CreatePage(): news layout: " + newsLayout, GetType().ToString());
            Logger.LogInfo("AddAnnouncement.CreatePage(): before publishingWeb.GetPublishingPages().Add - " + pageName, GetType().ToString());

            var list = web.Lists["Lehed"];
            var pages = publishingWeb.GetPublishingPages();
            Logger.LogInfo("AddAnnouncement.CreatePage(): publishing pages retrieved",  GetType().ToString());
            var pageUrl = list.RootFolder.ServerRelativeUrl + "/" + pageName;
            var publishingPage = pages.Add(pageUrl, newsLayout);
            Logger.LogInfo("AddAnnouncement.CreatePage(): publishing page created", GetType().ToString());

            //var publishingPage = publishingWeb.GetPublishingPages().Add(list.RootFolder.ServerRelativeUrl + "/" + pageName, newsLayout);
            var item = publishingPage.ListItem;
            item["ContentTypeId"] = web.Site.RootWeb.ContentTypes["Uudis"].Id;
            item["Title"] = titleField.Text;
            item.Update();
            publishingPage.Update();
            //publishingPage.PublishingWeb.Update();

            return publishingPage;
        }

        private void ApplyErrors(Dictionary<string, string> errors)
        {
            foreach (var fieldKey in errors.Keys)
            {
                var error = errors[fieldKey];
                var ctl = (HtmlGenericControl)this.FindControl(fieldKey + "Container", true);
                if (ctl == null)
                {
                    Response.Write("Ei leia konteinerit: " + fieldKey + "Container<br>");
                    Response.End();
                }
                else 
                    ctl.Attributes.Add("class", "info-row failed-info");

                ctl = (HtmlGenericControl)this.FindControl(fieldKey + "ErrorMessage", true);
                if (ctl == null)
                {
                    Response.Write("Ei leia konteinerit: " + fieldKey + "ErrorMessage<br>");
                    Response.End();
                }
                else 
                    ctl.Visible = true;

                ctl = (HtmlGenericControl)this.FindControl(fieldKey + "ErrorLabel", true);
                if (ctl == null)
                {
                    Response.Write("Ei leia konteinerit: " + fieldKey + "ErrorLabel<br>");
                    Response.End();
                }
                else 
                    ctl.InnerText = error;

                ctl = (HtmlGenericControl)this.FindControl(fieldKey + "ErrorNote", true);
                if (ctl == null)
                {
                    Response.Write("Ei leia konteinerit: " + fieldKey + "ErrorNote<br>");
                    Response.End();
                }
                else 
                    ctl.Visible = true;
            }
        }

        private void BindCompanies()
        {
            var repository = new CompanyRepository(SPContext.Current.Web);
            var companies = repository.GetApprovedCompanies();

            //companiesList.DataSource = companies.OrderBy(c => c.Title);
            //companiesList.DataBind();
            companiesDropDown.DataSource = companies.OrderBy(c => c.Title);
            companiesDropDown.DataBind();

            companiesDropDown.Items.Insert(0, new ListItem("- Puudub -", string.Empty));

            if (Item == null)
                return;

            if (Item.Companies == null)
                return;

            if(Item.Companies != null)
                if(Item.Companies.Count > 0)
                {
                    var company = Item.Companies[0];
                    if (company != null)
                        if (companiesDropDown.Items.FindByValue(company.Id.ToString()) != null)
                            companiesDropDown.SelectedValue = company.Id.ToString();
                }
            
            //foreach(var company in Item.Companies)
            //    foreach(ListItem item in companiesList.Items)
            //    {
            //        if(item.Value == company.Id.ToString())
            //        {
            //            item.Selected = true;
            //            break;
            //        }
            //    }
        }

        //private IList<int> GetSelectedCompanyIds()
        //{
        //    var idList = new List<int>();

        //    foreach (ListItem item in companiesList.Items)
        //        if (item.Selected)
        //            idList.Add(int.Parse(item.Value));

        //    return idList;
        //}

        private void AddApproverRoleToUser()
        {
            var userId = SPContext.Current.Web.CurrentUser.LoginName;
            var siteId = SPContext.Current.Site.ID;
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (var pubsite = new SPSite(siteId))
                using (var pubweb = pubsite.OpenWeb("/uudised/teated/"))
                {
                    pubweb.AllowUnsafeUpdates = true;
                    var pubList = pubweb.Lists["Lehed"];

                    var cuser = pubweb.SiteUsers[userId];

                    var assq = from a in pubList.RoleAssignments.Cast<SPRoleAssignment>()
                               from r in a.RoleDefinitionBindings.Cast<SPRoleDefinition>()
                               where a.Member.Name == cuser.LoginName &&
                                     r.Name == "Kinnitamine"
                               select a;

                    if (assq.Count() == 0)
                    {
                        Logger.LogInfo("SaveButtonClick(): assq is 0", GetType().ToString());
                        var ass2 = new SPRoleAssignment(cuser);
                        var rb2 = pubweb.RoleDefinitions["Kinnitamine"];
                        Logger.LogInfo("SaveButtonClick(): pubList.RoleAssignments = " + pubList.RoleAssignments.Count, GetType().ToString());
                        ass2.RoleDefinitionBindings.Add(rb2);
                        pubList.RoleAssignments.Add(ass2);
                        pubList.Update();
                    }
                    pubweb.AllowUnsafeUpdates = false;

                }
            });
        }

        private void RemoveApproverRoleFromUser()
        {
            var userId2 = SPContext.Current.Web.CurrentUser.LoginName;
            var siteId = SPContext.Current.Site.ID;
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (var pubsite = new SPSite(siteId))
                using (var pubweb = pubsite.OpenWeb("/uudised/teated/"))
                {
                    pubweb.AllowUnsafeUpdates = true;
                    var pubList = pubweb.Lists["Lehed"];

                    var cuser = pubweb.SiteUsers[userId2];

                    //var ass = pubList.RoleAssignments.GetAssignmentByPrincipal(cuser);
                    pubList.RoleAssignments.Remove(cuser);
                    pubList.Update();
                    pubweb.AllowUnsafeUpdates = false;
                }
            });  
        }
    }
}